/**
 * 
 */
package com.usc.nearbyus;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.io.StringWriter;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.List;

import org.xmlpull.v1.XmlSerializer;

import edu.usc.imsc.icampus.client.activities.SubmitData;

import android.app.Activity;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.Intent;
import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
import android.os.SystemClock;
import android.util.Log;
import android.util.Xml;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

/**
 * @author pranav
 *
 */
public class GPSLoggingTest extends Activity implements OnClickListener {

	/*
	 * This offset deals with the following tags & it's removal for the rewrite of the file 
	 * </channel></rss>
	 */
	private static long XML_INSERT_OFFSET = 16;
	private Button startLogging;
	private Button loggingInterval;
	private String TAG = "GPSLoggingTest";
	private Button storedata;
	private ReadingsDbAdapter mDbAdapter;
	private Button submitData;

	/* (non-Javadoc)
	 * @see android.app.Activity#onCreate(android.os.Bundle)
	 */
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);

		setContentView(R.layout.gpstest);


		startLogging = (Button)findViewById(R.id.startgpslogging);
		loggingInterval = (Button)findViewById(R.id.logging_interval);
		storedata = (Button)findViewById(R.id.storedata);
		submitData = (Button) findViewById(R.id.submitdata);

		startLogging.setOnClickListener(this);
		loggingInterval.setOnClickListener(this);
		storedata.setOnClickListener(this);
		submitData.setOnClickListener(this);
	}

	@Override
	public void onClick(View v) {

		switch(v.getId()){
		case R.id.startgpslogging:
			// toggleLogging(false, 500);

			getApplicationContext().startService(new Intent(getApplicationContext(),GPSLoggerService.class));
			break;			
		case R.id.logging_interval:
			changeLoggingInterval();
			break;

		case R.id.storedata:
			storeDataOnExternalStorage();
			break;
			
		case R.id.submitdata:
			Intent intent = new Intent(getApplicationContext(),SubmitData.class);
			startActivity(intent);
			break;
		}

	}

	private void storeDataOnExternalStorage() {

		mDbAdapter = new ReadingsDbAdapter(getApplicationContext());
		mDbAdapter.open();


		List<GeoRssItem> items = new ArrayList<GeoRssItem>();

		Cursor cur = mDbAdapter.getAllReadings();

		cur.moveToFirst();
		while (cur.isAfterLast() == false) {

			GeoRssItem geoItem = new GeoRssItem(cur.getString(1),cur.getString(2),cur.getString(3),cur.getString(4),
					cur.getString(5),cur.getString(6),cur.getString(7),cur.getString(8),cur.getString(9),cur.getString(10));

			items.add(geoItem);

			cur.moveToNext();
		}
		cur.close();

		writeXml(items);
		
		mDbAdapter.close();


	}


	private void writeXml(List<GeoRssItem> items){

		File folder = new File(Environment.getExternalStorageDirectory(), "nearbyus");
		boolean isNew = false;

		if (!folder.exists())
		{
			boolean folderCheck = folder.mkdirs();
			if(folderCheck){
				Log.d(TAG, "Directory Created");				
			}else{
				Log.d(TAG, "Directory not created");
			}
			isNew = true;
		}

		try {			

			File readingsFile = new File(folder.getPath(),"readings.xml");

			while (!readingsFile.exists())
			{
				readingsFile.createNewFile();				
				isNew = true;
			}

			if(isNew)
			{
				FileOutputStream initialWriter = new FileOutputStream(readingsFile,true);


				XmlSerializer serializer = Xml.newSerializer();
				StringWriter writer = new StringWriter();
				serializer.setOutput(writer);
				serializer.startDocument("UTF-8", false);		
				serializer.setPrefix("georss", "http://www.georss.org/georss");	
				serializer.setPrefix("gml", "http://www.opengis.net/gml");	
				serializer.startTag("", "rss");
				
				serializer.startTag("", "channel");				
				//serializer.attribute("", "link", "https://sites.google.com/site/nearbyus/");
				serializer.startTag("", "link");
				serializer.text("https://sites.google.com/site/nearbyus/");
				serializer.endTag("", "link");
				serializer.startTag("", "title");
				serializer.text("WiFi Tracking Submission from NearbyUs");
				serializer.endTag("", "title");

				for (GeoRssItem item: items){

					serializer.startTag("", "item");

					serializer.startTag("", "pubDate");
					serializer.text(item.getTimestamp());
					serializer.endTag("", "pubDate");
					

					serializer.startTag("", "title");
					serializer.text(item.getSsid());
					serializer.endTag("", "title");

					serializer.startTag("", "description");
					serializer.text("WiFi Signal Reading");
					serializer.endTag("", "description");

					//TODO - PV check the userid generation : should be unique for a user
					serializer.startTag("", "author");
					serializer.text(item.getUserid());
					serializer.endTag("", "author");
					
					serializer.startTag("", "georss:point");
					serializer.text(item.getLatitude()+" "+item.getLongitude());				
					serializer.endTag("", "georss:point");

					serializer.startTag("", "summary");
					serializer.text(item.getLevel());
					serializer.endTag("", "summary");

					//TODO - PV check the hardcoded value here
					serializer.startTag("", "georss:radius");
					serializer.text("2");
					serializer.endTag("", "georss:radius");

					serializer.startTag("", "isFlaggedByUser");
					serializer.text(item.getIsflagged());
					serializer.endTag("", "isFlaggedByUser");

					//TODO - PV check the hardcoded value here
					serializer.startTag("", "hasBeenSmoothed");
					serializer.text("false");
					serializer.endTag("", "hasBeenSmoothed");

					serializer.endTag("", "item");	


				}

				serializer.endTag("", "channel");
				serializer.endTag("", "rss");
				serializer.endDocument();				

				initialWriter.write(writer.toString().getBytes());
				initialWriter.flush();
				initialWriter.close();

			} else{

				RandomAccessFile fileAccess = new RandomAccessFile(readingsFile, "rw");
				FileLock lock = fileAccess.getChannel().lock();						

				try{

					fileAccess.seek((readingsFile.length() - GPSLoggingTest.XML_INSERT_OFFSET));

					Log.d(TAG, "Seek position : " + fileAccess.getFilePointer() );
					byte[] buffer = new byte[100];
					fileAccess.read(buffer);
					Log.d(TAG, "What the hell did we read ? : " + new String(buffer));
					
					fileAccess.seek((readingsFile.length() - GPSLoggingTest.XML_INSERT_OFFSET));

					XmlSerializer serializer = Xml.newSerializer();
					StringWriter writer = new StringWriter();
					serializer.setOutput(writer);

					for (GeoRssItem item: items){

						serializer.startTag("", "item");

						serializer.startTag("", "pubDate");
						serializer.text(item.getTimestamp());
						serializer.endTag("", "pubDate");

						serializer.startTag("", "title");
						serializer.text(item.getSsid());
						serializer.endTag("", "title");

						serializer.startTag("", "description");
						serializer.text("WiFi Signal Reading");
						serializer.endTag("", "description");

						//TODO - PV check the userid generation : should be unique for a user
						serializer.startTag("", "author");
						serializer.text(item.getUserid());
						serializer.endTag("", "author");

						serializer.startTag("", "georss:point");
						serializer.text(item.getLongitude()+" "+item.getLatitude());
						serializer.endTag("", "georss:point");

						serializer.startTag("", "summary");
						serializer.text(item.getLevel());
						serializer.endTag("", "summary");


						//TODO - PV check the hardcoded value here
						serializer.startTag("", "georss:radius");
						serializer.text("2");
						serializer.endTag("", "georss:radius");

						serializer.startTag("", "isFlaggedByUser");
						serializer.text(item.getIsflagged());
						serializer.endTag("", "isFlaggedByUser");

						//TODO - PV check the hardcoded value here
						serializer.startTag("", "hasBeenSmoothed");
						serializer.text("false");
						serializer.endTag("", "hasBeenSmoothed");

						serializer.endTag("", "item");		
						
					}			
				/*	
					serializer.endTag("", "channel");
					serializer.endTag("", "rss");
					
				//	serializer.text('<'+"/channel"+'>'+'<'+"/rss>");				
					char[] buf = new char[new String("</channel></rss>").length()];
					buf = ("</channel></rss>").toCharArray();
					serializer.text(buf, 0, buf.length);

					serializer.endTag("", "channel");
					serializer.endTag("", "rss");
				*/
					serializer.endDocument();

					
					// Had to manually add the last 2 tags + as serializer object would not allow me to add 
					// using the endTag [ as while appending to the file we do not start the tag ]
					fileAccess.writeBytes(writer.toString()+"</channel></rss>");

				}
				finally {
					
					try {
						
						if(lock != null){
							lock.release();
							}

						if (fileAccess != null){
							fileAccess.close();
						}
						
						

					} catch (IOException ex) {
						ex.printStackTrace();
					}
				}


			}	


		} catch (IOException e) {
			throw new RuntimeException(e);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}		
	}

	private void changeLoggingInterval() {
		// TODO Auto-generated method stub

	}

	private void toggleLogging(boolean isStart, int interval){
		AlarmManager manager = (AlarmManager)getSystemService(Service.ALARM_SERVICE);
		PendingIntent loggerIntent = PendingIntent.getBroadcast(this, 0,new Intent(this,AlarmReceiver.class), 0);

		if(isStart){
			manager.cancel(loggerIntent);			
			//	AppSettings.setServiceRunning(this, false);
			Log.d(TAG , " Alarmservice stopped ");
		}
		else{

			long duration = interval * 60 * 1000;			
			manager.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
					SystemClock.elapsedRealtime(), duration, loggerIntent);

			// AppSettings.setServiceRunning(this, true);

			Log.d(TAG, "Service Started with interval : " + interval);	

		}
	}	

}
